package cn.mesmile.thread;

import cn.hutool.core.thread.ThreadFactoryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author zb
 * @date 2020/12/28 19:33
 * @Description
 */
public class TreadFor {
    private static final int loopNum = 1*10;

    /**
     * Executors.newCachedThreadPool()	创建一个可根据需要创建新线程的线程池
     * Executors.newFixedThreadPool(n)	创建一个可重用固定线程数的线程池
     * Executors.newSingleThreadExecutor()	:创建一个只有一个线程的线程池
     * Executors.newScheduledThreadPool(n)	创建一个线程池，它可安排在给定延迟后运行命令或者定期地执行。
     *
     * corePoolSize:核心池线程的大小  --》 线程池的基本大小，即在没有任务需要执行的时候线程池的大小，并且只有在工作队列满了的情况下才会创建超出这个数量的线程
     * maximumPoolSize:最大线程数  --》 线程池中的当前线程数目不会超过该值
     * keepAliveTime：线程没有任务时最多保持多长时间后会终止
     *
     * corePoolSize 线程池基本大小
     * maximumPoolSize 线程池最大数
     * poolSize: 当前线程数
     *
     * 当poolSize < corePoolSize, 无论是否其中有空闲的线程，都会给新的任务产生新的线程
     * 当corePoolSize<poolSize<maximumPoolSize, 而又有空闲线程，就给新任务使用空闲线程，如没有空闲线程，则放入workQueue中，当workQueue已满，则创建新的线程
     * 当poolSize>maximumPoolSize，那么后面来的任务默认都会被拒绝--通常都会报异常
     *
     * // IO密集型 有大量阻塞  【核心池线程数=  8核CPU：8/（1-0.9） = 80个线程数】 【核心池线程数=  8核CPU：8/（1-0.8） = 160个线程数】
     * allowCoreThreadTimeOut：
     * 该属性用来控制是否允许核心线程超时退出。If false,core threads stay alive even when idle.If true, core threads use keepAliveTime to time out waiting for work。如果线程池的大小已经达到了corePoolSize，不管有没有任务需要执行，线程池都会保证这些核心线程处于存活状态。可以知道：该属性只是用来控制核心线程的。
     *
     * keepAliveTime：
     * 如果一个线程处在空闲状态的时间超过了该属性值，就会因为超时而退出。举个例子，如果线程池的核心大小corePoolSize=5，而当前大小poolSize =8，那么超出核心大小的线程，会按照keepAliveTime的值判断是否会超时退出。如果线程池的核心大小corePoolSize=5，而当前大小poolSize =5，那么线程池中所有线程都是核心线程，这个时候线程是否会退出，取决于allowCoreThreadTimeOut。
     *
     * JDK 5.0 起提供了线程池相关API：ExecutorService 和 Executors
     * ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor.
     * void execute(Runnable coommand):执行任务/命令，没有返回值，一般用来执行Runnable
     * Future submit(Callable task):执行任务，有返回值，一般又来执行Callable
     * void shutdown（）：关闭连接池。
     *
     */

    public static void main(String args[]) throws InterruptedException {
        // 查看电脑核心数
        int i = Runtime.getRuntime().availableProcessors();
        // i = 8  8 核心数
        System.out.println("corePoolSize : "+ i);


        TreadFor treadFor = new TreadFor();
        long bt = System.currentTimeMillis();
        List<String> list = new ArrayList<>();
        list.add("0");list.add("1");list.add("2");list.add("3");
        list.add("4");list.add("5");list.add("6");
        list.add("7");list.add("8");list.add("9");list.add("10");
        treadFor.m1(list);
        long et2 = System.currentTimeMillis();
        System.out.println("[1]耗时:"+(et2 - bt)+ "ms");

//        Thread thread = new Thread();
//        long at = System.currentTimeMillis();
//        treadFor.m2();
//        long et3 = System.currentTimeMillis();
//        System.out.println("[2]耗时:"+(et3 - at)+ "ms");

    }

    public void m1( List<String> list) {

        /*
         *   corePoolSize:核心池的大小
         *   maximumPoolSize:最大线程数
         *   keepAliveTime：线程没有任务时最多保持多长时间后会终止
         */
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder()
                .setNamePrefix("demo-pool-%d-").build();
        ExecutorService singleThreadPool = new ThreadPoolExecutor(1, 10,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>(1024),
                namedThreadFactory,
                new ThreadPoolExecutor.AbortPolicy());

        singleThreadPool.execute(
                new Runnable() {
                    @Override
                    public void run() {
                        System.out.println(">>>>>>>>>>>>>>> -------------");
                    }
                }
        );
        singleThreadPool.shutdown();

        // 创建一个可根据需要创建新线程的线程池
        ExecutorService pool = Executors.newCachedThreadPool();

        for (int i = 0; i < list.size(); i++) {
            String str = list.get(i);
            System.out.println(list.get(i));
            Runnable run = new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(100);
                        //模拟耗时操作
                        System.out.println("[1]" + Thread.currentThread().getName()+"----"+str);
                    } catch (Exception e) {

                    }
                }
            };
            // 线程池执行没有返回值
            pool.execute(run);
        }
        System.out.println("[1] done!");
        // 关闭线程池
        pool.shutdown();
    }

    public void m2() {
        AtomicInteger connectionIds = new AtomicInteger(0);
        for (int index = 0; index < loopNum; index++) {
            try {
                //模拟耗时操作
                Thread.sleep(1000);
                System.out.println("[2]" + Thread.currentThread().getName());

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("[2] done!");
    }
}
